Expand description

Provides pre-rasterized characters from the “Noto Sans Mono” font in different sizes and font weights for multiple unicode ranges. This crate is no_std and needs no allocations or floating point operations. Useful in kernels and bootloaders when only “soft-float” is available. Strictly speaking, this crate is more than a basic bitmap font, because it encodes each pixel as a byte and not as a bit, which results in a much nicer result on the screen.

TL;DR

  • no_std, zero allocations, no floating point operations
  • ✅ most important symbols, numbers, and letters as pre-rasterized constant. Unicode-ranges are selectable.
  • ✅ Noto Sans Mono font as base
  • ✅ different sizes and font weights (light, normal, bold)
  • ✅ nice anti-aliasing/smoothing and better looking than legacy bitmap fonts
  • ✅ every pixel is encoded in a byte (0-255) and not a bit, which results in a much nicer result on the screen.
  • ✅ relevant font sizes, such as 14, 18, 22, and 32px (as optional build time features)
  • ✅ zero dependencies
  • ✅ All characters are aligned in their box/raster. If they are printed next to each other, the result looks nice.

Terminology: Is Bitmap Font The Right Term?

Legacy (8x8) bitmap fonts usually refer to a font where each symbol is encoded in 8 bits. The ones in a byte (0b00110000) means “pixel on” and the zeroes’ means “pixel off”. However, my font actually encodes the intensity of each pixel as a byte from 0 to 255. Hence, this is less size efficient than legacy bitmap fonts, but looks much better. I still use the term bitmap font, because that term is used and known when talking about pre-rasterized fonts/font rendering in low-level contexts, such as the boot process.

When To Use This Crate

If you want to print to a framebuffer and if you develop a bootloader or a kernel, you usually don’t want to enable the FPU and refrain from floating point instruction (i.e. only use soft float). My crate is a good option to print characters nicely to the screen in such scenarios. As nice live font rendering of TTF fonts heavily relies on many floating point operations, which is not optimal inside a low level binary. Legacy 8x8 bitmap fonts are ugly when printed to the screen. noto_sans_mono_bitmap can be seen as a nice replacement with very nice anti-aliasing.

Minimal Code Example

use noto_sans_mono_bitmap::{get_raster, get_raster_width, RasterHeight, FontWeight};

// Minimal example.

let width = get_raster_width(FontWeight::Regular, RasterHeight::Size16);
println!(
    "Each char of the monospaced font will be {}px in width if the font \
     weight is {:?} and the height is {}",
    width,
    FontWeight::Regular,
    RasterHeight::Size16.val()
);
let char_raster = get_raster('A', FontWeight::Regular, RasterHeight::Size16).expect("unsupported char");
println!("{:?}", char_raster);
for (row_i, row) in char_raster.raster().iter().enumerate() {
    for (col_i, pixel) in row.iter().enumerate() {
        println!("[{:02}][{:02}]: {:03}", row_i, col_i, pixel);
    }
}

Cargo Features and Crate Size

By default, only a reasonable subset of possible features is included. The raw crate-size is a few MiB in size but after compilation and discarding irrelevant parts (i.e., size 14, regular font, only ASCII), the overhead should be at less than 100-200 KiB in binary size, according to my measurements. The compiler can reliably discard unused sizes or weights, but not so for unicode ranges. Thus, it is recommended to include no more features than necessary.

With all features included inside the binary, and without any discarding by the compiler, you can expect 5 or more MiB of memory requirements. However, this would require the rather unlikely case that you use different sizes and font weights simultaneously.

Not all unicode ranges include all symbols. Control characters are not there as well as protected spaces and similar characters. For a full support of all unicode ranges, use an on-the-fly rasterization process instead of this crate.

Structs

Describes the relevant information for a rendered char of the font.

Enums

Supported font weights.
The height of the pre-rasterized font. The font size will be a a few percent less, because each letter contains vertical padding for proper alignment of chars (i.e. ÄyA). The width of each character will be also less than the height, because there is no horizontal padding included.

Functions

Returns a RasterizedChar for the given char, FontWeight, and RasterHeight.
Returns the width in pixels a char will occupy on the screen. The width is constant for all characters regarding the same combination of FontWeight and RasterHeight. The width is a few percent smaller than the height of each char